import axios, { AxiosInstance, AxiosResponse, InternalAxiosRequestConfig } from 'axios';
import { ElMessage, ElMessageBox } from 'element-plus';
import { getToken, getTokenHeader, isLogin } from '@/utils/auth.ts';
import useUserStore from '@/store/modules/user';

const baseApi = import.meta.env.VITE_BASE_API;
const isDevelopment = ['development', 'dev'].includes(import.meta.env.MODE);

// 创建 axios 实例
const service: AxiosInstance = axios.create({
  baseURL: baseApi, // api 的 base_url
  timeout: 60 * 1000, // 请求超时时间
  withCredentials: true, // 跨域请求时发送 cookies
})

// 添加 request请求 拦截器
service.interceptors.request.use((config: InternalAxiosRequestConfig<any>) => {
  // console.log(config);
  config.headers['action'] = config.params && config.params.action;
  // 如果已登录
  if (isLogin()) {
    let header = getTokenHeader();
    if (header) {
      // 请求头部添加令牌信息getToken()
      config.headers["token"] = getToken()
      // config.headers["token"] = "admin1"

    }
  }
  // 返回配置信息
  return config
}, (error: any) => {
  if (isDevelopment) console.log('请求异常: ', error)
  return Promise.reject(error);
})

// 添加 response响应 拦截器
service.interceptors.response.use((response: AxiosResponse<any, any>) => {
  const data = response.data
  // 处理文件下载业务
  if (data && data instanceof Blob) {
    return data;
  }
  // if (isDevelopment) console.log('响应 => ' + response.config.url, data)
  let code = data.status || -1

  if (code !== 0 && code != 200 &&code!==10000) {
    let message = data.message || data.msg
    if (code === 401) {
      // 无权限
      return handleUnauthorized(message);

    } else if (code === 901 || code===80003) {
      // 令牌失效
      return handleTokenInvalid();
    } else {
      ElMessage.error({message: message, duration: 3 * 1000})
    }
    return Promise.reject(message)
  }
  return data
}, (error: any) => {
  if (isDevelopment) console.log('响应异常 => ' + error.response.config.url, error)
  let message = error.message
  if (error && error.response) {
    switch (error.response.status) {
      case 400:
        message = '请求错误'
        break
      case 401:
        message = '无权限访问该资源'
        break
      case 403:
        message = '拒绝访问'
        break
      case 404:
        message = `请求地址不存在`
        if (isDevelopment) message += `: ${error.response.config.url}`
        break
      case 408:
        message = '请求超时'
        break
      case 500:
        message = '服务器内部错误'
        break
      case 501:
        message = '服务未实现'
        break
      case 502:
        message = '网关错误'
        break
      case 503:
        message = '服务不可用'
        break
      case 504:
        message = '网关超时'
        break
      case 505:
        message = 'HTTP版本不受支持'
        break
      default:
        break
    }
  }
  if (message) {
    ElMessage.error({message: message, duration: 3 * 1000})
  }
  return Promise.reject(error)
})

/**
 * 请求地址处理
 * @param {*} actionName action方法名称
 */
export const getRequestUrl = (actionName: any) => {
  return baseApi + actionName
}

/**
 * 通用的数据下载
 * @param url
 * @param params
 */
export const download = async <T = any>(url: string, params: any) => {
  const res = await service({url: url, params: params, method: 'GET', responseType: 'blob'});
  return res as unknown as Promise<T>
}

/** 处理无权限 */
const handleUnauthorized = (message?: string) => {
  if (message) {
    ElMessage.error({message: message, duration: 3 * 1000})
  }
  return Promise.reject('无权限访问该资源');
}

/** 处理令牌失效 */
const handleTokenInvalid = () => {
  // 如果页面已经是登录页 不进行弹窗显示
  if (window.location.href.includes('login')) {
    return
  }
  // 弹出确认提示框
  ElMessageBox.confirm('登录状态已过期，请重新登录!', '系统提示', {
    confirmButtonText: '重新登录',
    closeOnClickModal: false,
    showCancelButton: false,
    showClose: false,
    type: 'warning'
  }).then(() => {
    // 清理登录信息
    const userStore = useUserStore();
    userStore.clearInfo().then(() => {
      // 为了重新实例化vue-router对象 避免bug
      localStorage.removeItem('oathShow')
      location.reload();
    });
  });
  return Promise.reject('登录状态已过期，请重新登录!');
}

export default service
